package cn.bupt.adt.service.impl;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.bupt.adt.constant.Constants;
import cn.bupt.adt.dao.autogenerate.DoctorAppUserMapper;
import cn.bupt.adt.dao.autogenerate.DoctorMapper;
import cn.bupt.adt.dao.autogenerate.DoctorOperationTypeViewMapper;
import cn.bupt.adt.dao.autogenerate.Doctor_OperationTypeMapper;
import cn.bupt.adt.dao.autogenerate.OperationTypeMapper;
import cn.bupt.adt.dao.autogenerate.SubOperationTypeMapper;
import cn.bupt.adt.entity.autogenerate.Doctor;
import cn.bupt.adt.entity.autogenerate.DoctorAppUser;
import cn.bupt.adt.entity.autogenerate.DoctorAppUserExample;
import cn.bupt.adt.entity.autogenerate.DoctorOperationTypeView;
import cn.bupt.adt.entity.autogenerate.DoctorOperationTypeViewExample;
import cn.bupt.adt.entity.autogenerate.Doctor_OperationType;
import cn.bupt.adt.entity.autogenerate.Doctor_OperationTypeExample;
import cn.bupt.adt.entity.autogenerate.OperationType;
import cn.bupt.adt.entity.autogenerate.OperationTypeExample;
import cn.bupt.adt.entity.autogenerate.Order;
import cn.bupt.adt.entity.autogenerate.SubOperationType;
import cn.bupt.adt.entity.autogenerate.SubOperationTypeExample;
import cn.bupt.adt.model.DoctorModel;
import cn.bupt.adt.service.IDoctorAppUserService;
import cn.bupt.adt.service.IDoctorService;
import cn.bupt.adt.util.AccountUtil;
import cn.bupt.adt.util.BeanUtil;
import cn.bupt.adt.util.MD5Util;
import cn.bupt.adt.util.NetDataAccessUtil;
import cn.bupt.adt.util.SendSMSUtil;
@Service
public class DoctorServiceImpl implements IDoctorService {

	@Autowired
	DoctorMapper doctorMapper;
	
	@Autowired 
	OperationTypeMapper operationTypeMapper;
	
	@Autowired
	Doctor_OperationTypeMapper doctor_OperationTypeMapper;
	
//	@Autowired
//	DoctorViewMapper doctorViewMapper;
	
	@Autowired
	DoctorAppUserMapper doctorAppUserMapper;
	
	@Autowired
	DoctorOperationTypeViewMapper doctorOperationTypeViewMapper;
	
	@Autowired
	IDoctorAppUserService doctorAppUserService;
	
	@Autowired
	SubOperationTypeMapper subOperationTypeMapper;
	@Transactional
//	public boolean addDoctor(Doctor doc, HttpServletRequest request,int[] operationTypeId) {
//		MultipartHttpServletRequest req = (MultipartHttpServletRequest) request;
//		//rootPath = 项目所在目录+分隔符+upload+分隔符
//		String rootPath = req.getSession().getServletContext().getRealPath("")+"/../"+Constants.IMAGE_PATH;
//		List<MultipartFile> degs = req.getFiles("degs");
////		List<MultipartFile> idCards = req.getFiles("idCards");
//		List<MultipartFile> quas = req.getFiles("quas");
//		List<MultipartFile> certs = req.getFiles("certs");
//		List<MultipartFile> pros = req.getFiles("pros");
//		MultipartFile idPos = req.getFile("idPos");
//		MultipartFile idNeg = req.getFile("idNeg");
//		Long time = System.currentTimeMillis();
//		String timePath = time.toString()+"/";
//		MultipartFile portrait = req.getFile("portr");
//		List<String> path = new ArrayList<>();
//		try {
//			path.add(ImageUtil.uploadImage(portrait, Constants.DOC_PORTRAIT+timePath, rootPath,1));
//			ObjectMapper mapper = new ObjectMapper();
//			doc.setPortrait(path.get(0));
//			path.clear();
//			int i = 0;
//			for(MultipartFile degFile:degs) {
//				path.add(ImageUtil.uploadImage(degFile, Constants.DEG_PATH+timePath, rootPath,i));
//				i++;
//			}
//			mapper = new ObjectMapper();
//			doc.setDegreeImg(mapper.writeValueAsString(path));
//			path.clear();
//			i = 0;
//			for(MultipartFile idCardFile:idCards) {
//				path.add(ImageUtil.uploadImage(idCardFile, Constants.IDEN_PATH+timePath, rootPath,i));
//				i++;
//			}
//			doc.setIdentificationImg(mapper.writeValueAsString(path));
//			path.clear();
//			i = 0;
//			for(MultipartFile quaFile:quas) {
//				path.add(ImageUtil.uploadImage(quaFile, Constants.QUA_PATH+timePath, rootPath,i)) ;
//				i++;
//			}
//			doc.setQualificationImg(mapper.writeValueAsString(path));
//			path.clear();
//			i = 0;
//			for(MultipartFile certFile:certs) {
//				path.add(ImageUtil.uploadImage(certFile, Constants.CERT_PATH+timePath, rootPath,i));
//				i++;
//			}
//			doc.setCertificationImg(mapper.writeValueAsString(path));
//			path.clear();
//			i = 0;
//			for(MultipartFile proFile:pros) {
//				path.add( ImageUtil.uploadImage(proFile, Constants.PRO_PATH+timePath, rootPath,i));
//				i++;
//			}
//			doc.setProfessionalTitleImg(mapper.writeValueAsString(path));
//		}
//		catch(Exception e){
//			
//		}
//		List<Doctor> existsDoctors = doctorMapper.selectByExample(new DoctorExample());
//		for(Doctor d:existsDoctors)
//			if(d.getPhone().equals(doc.getPhone()))
//				return false;
//		DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//		doc.setInvitaCode(MD5Util.MD5(doc.getPhone()+df.format(new Date())));
//		int i = doctorMapper.insert(doc);
//		SendSMSUtil sendSms = new SendSMSUtil();
//		sendSms.SendSMS(doc.getPhone(), new String[]{doc.getInvitaCode()}, Constants.SMS_INVATECODE);
//		for(int x:operationTypeId) {
//			Doctor_OperationType dot = new Doctor_OperationType();
//			dot.setDoctorId(doc.getId());
//			dot.setOperationTypeId(x);
//			doctor_OperationTypeMapper.insert(dot);
//		}
//		return i==1;
//	}


	public boolean removeDoctor(Doctor doc) {
		// TODO Auto-generated method stub
		return false;
	}

	public List<DoctorModel> getAllDoctor(HttpServletRequest request) {
		DoctorAppUserExample ex = new DoctorAppUserExample();
		ex.createCriteria().andReviewStatusIsNotNull();
		List<DoctorAppUser> doctors = doctorAppUserMapper.selectByExample(ex);
		List<DoctorModel> res = new ArrayList<>(doctors.size());
		StringBuilder sb = new StringBuilder();
		for(DoctorAppUser doc:doctors) {
			if(doc.getReviewStatus() == null)
				continue;
			DoctorModel dm = new DoctorModel();
			try {
				BeanUtil.fatherToChild(doc, dm);
			} catch (Exception e) {
				e.printStackTrace();
			}
//			dm.setIdens(ImageUtil.convertToList(dm.getIdentificationImg()));
			List<DoctorOperationTypeView> lables = getOperationTypesByDoctorId(doc.getId());
			int count = 0;
			for(DoctorOperationTypeView op:lables) {
				if(count < 3) {
					sb.append(op.getOperationTypeName());
					sb.append(',');
					++count;
				}
				else
					break;
			}
			if(sb.length() != 0)
				dm.setLabels(sb.substring(0, sb.length()-1));	
			else
				dm.setLabels("");
			sb.delete(0, sb.length());
			res.add(dm);
		}
		return res;
	}
	private List<DoctorModel> transferModel(List<DoctorAppUser> doctors){
		List<DoctorModel> res = new ArrayList<>(doctors.size());
		StringBuilder sb = new StringBuilder();
		for(DoctorAppUser doc:doctors) {
			if(doc.getReviewStatus() == null)
				continue;
			DoctorModel dm = new DoctorModel();
			try {
				BeanUtil.fatherToChild(doc, dm);
			} catch (Exception e) {
				e.printStackTrace();
			}
//			dm.setIdens(ImageUtil.convertToList(dm.getIdentificationImg()));
			List<DoctorOperationTypeView> lables = getOperationTypesByDoctorId(doc.getId());
			int count = 0;
			for(DoctorOperationTypeView op:lables) {
				if(count < 3) {
					sb.append(op.getOperationTypeName());
					sb.append(',');
					++count;
				}
				else
					break;
			}
			dm.setLabels(sb.substring(0, sb.length()-1));		
			sb.delete(0, sb.length());
			res.add(dm);
		}
		return res;
	}
	@Override
	public List<OperationType> getAllOpertionType() {
		OperationTypeExample example = new OperationTypeExample();
		example.createCriteria().andDeleteFlagEqualTo(false);
		return operationTypeMapper.selectByExample(example);
	}

	@Override
	public boolean addOperationType(OperationType type) {
		type.setDeleteFlag(false);
		int i = operationTypeMapper.insert(type);
		return i == 1;
	}
	//删除1级手术类型需要做三件事
	//1.删除该类型(deleteFlag置为1)
	//2.删除该类型下所有二级类型(所有二级类型deleteFlag置为1)
	//3.医生-手术类型表相关记录删除
	@Override
	public boolean deleteOperationTypeById(int id) {
		OperationType operationType = new OperationType();
		SubOperationType subOperationType = new SubOperationType();
		operationType.setId(id);
		operationType.setDeleteFlag(true);
		subOperationType.setDeleteFlag(true);
		//1
		int i = operationTypeMapper.updateByPrimaryKeySelective(operationType);
		SubOperationTypeExample example = new SubOperationTypeExample();
		example.createCriteria().andParentIdEqualTo(id);
		//2
		subOperationTypeMapper.updateByExampleSelective(subOperationType, example);
		Doctor_OperationTypeExample doe = new Doctor_OperationTypeExample();
		doe.createCriteria().andOperationTypeIdEqualTo(id);
		//3
		doctor_OperationTypeMapper.deleteByExample(doe);
		return i == 1;
	}

	@Override
	public List<DoctorAppUser> getDoctorsByOrder(Order order) {
		//获取订单的2级手术id
		SubOperationType subOperationType = subOperationTypeMapper.selectByPrimaryKey(order.getSubOperationTypeId()) ;
		if(subOperationType == null)
			return new ArrayList<DoctorAppUser>();
		//根据2级id获取1级id
		int operationTypeId = subOperationType.getParentId();
		//剩下的处理流程和之前只有1级的时候一样了
		Doctor_OperationTypeExample ex = new Doctor_OperationTypeExample();
		ex.createCriteria().andOperationTypeIdEqualTo(operationTypeId);
		List<Doctor_OperationType> doctor_OperationTypes = doctor_OperationTypeMapper.selectByExample(ex);
		List<Integer> doctorIds = new ArrayList<Integer>(doctor_OperationTypes.size());		
		for(Doctor_OperationType dot:doctor_OperationTypes)
			doctorIds.add(dot.getDoctorId());
		DoctorAppUserExample dex = new DoctorAppUserExample();
		dex.createCriteria().andIdIn(doctorIds);
		return doctorAppUserMapper.selectByExample(dex);
	}
	
	@Override
	public DoctorModel getDoctorById(int id) {
		DoctorAppUser doc = doctorAppUserMapper.selectByPrimaryKey(id);
		DoctorModel dm = new DoctorModel();
		StringBuilder sb = new StringBuilder();
		if(doc != null) {
			if(doc.getReviewStatus() == null)
				return dm;
			try {
				BeanUtil.fatherToChild(doc, dm);
			} catch (Exception e) {
				e.printStackTrace();
			}
//			dm.setIdens(ImageUtil.convertToList(dm.getIdentificationImg()));
			List<DoctorOperationTypeView> lables = getOperationTypesByDoctorId(doc.getId());
			for(DoctorOperationTypeView op:lables) {
					sb.append(op.getOperationTypeName());
					sb.append(',');
			}
			if(sb.length() !=0)
				dm.setLabels(sb.substring(0, sb.length()-1));	
			else
				dm.setLabels("");
		}
		return dm;
	}
	
	@Override
	public int appointDoctor(Integer doctorId){
	
		SendSMSUtil sendSms = new SendSMSUtil();
		if (doctorId!=0) {
			DoctorModel doctor = getDoctorById(doctorId);
			NetDataAccessUtil nau = new NetDataAccessUtil();
			nau = sendSms.SendSMS(doctor.getPhone(), new String[]{"指派医生发短信"}, Constants.SMS_JIEDAN); 
			return nau.getResult();
		}
		else {
			return 0;
		}
	}

	@Override
	public boolean deleteDoctorById(int id) {
		return doctorAppUserMapper.deleteByPrimaryKey(id) == 1;
	}

	@Override
	public synchronized boolean addDoctor(DoctorAppUser doctor) {
		String invateCode = null;
		List<DoctorAppUser> doctors = doctorAppUserMapper.selectByExample(new DoctorAppUserExample());
		Set<String> set = new HashSet<String>(doctors.size());
		for(DoctorAppUser d:doctors) {
			if (d.getPhone().equals(doctor.getPhone())) {
				return false;
			}
			set.add(d.getInvitaCode());
		}
		do{
			invateCode = AccountUtil.getRandomInvitaCode(6);
		}while(set.contains(invateCode));
		doctor.setInvitaCode(invateCode);
		initializeDoctor(doctor);
		SendSMSUtil sendSms = new SendSMSUtil();
		int i = doctorAppUserMapper.insert(doctor);
		if(i == 1)
			sendSms.SendSMS(doctor.getPhone(), new String[]{doctor.getInvitaCode()}, Constants.SMS_INVATECODE);
		return i == 1;
	}
	private void initializeDoctor(DoctorAppUser doctor) {
		doctor.setMoney(0.0);
		doctor.setRiskMargin(0.0);
		doctor.setWaitedToBeWithdrawnMoney(0.0);
		doctor.setOperationSuccessNum(0);
		doctor.setTakeOrderNum(0);
		doctor.setFinishOrderMoney(0.0);
		doctor.setFinishOrderNum(0);
	}

	@Override
	public List<DoctorOperationTypeView> getOperationTypesByDoctorId(int id) {
		DoctorOperationTypeViewExample ex = new DoctorOperationTypeViewExample();
		ex.createCriteria().andDoctorIdEqualTo(id);
		return doctorOperationTypeViewMapper.selectByExample(ex);
	}

	@Override
	public boolean reviewDoctorById(int id) {
		DoctorAppUser d = new DoctorAppUser();
		d.setId(id);
		d.setReviewStatus(true);
		return doctorAppUserMapper.updateByPrimaryKeySelective(d) == 1;
	}

	@Override
	public boolean modifyDoctor(DoctorAppUser doc) {
		return false;
	}

	@Override
	public boolean modifyDoctor(DoctorAppUser doctor, HttpServletRequest request, int[] operationTypeId) {
		Doctor_OperationTypeExample ex = new Doctor_OperationTypeExample();
		ex.createCriteria().andDoctorIdEqualTo(doctor.getId());
		//删除原有标签
		doctor_OperationTypeMapper.deleteByExample(ex);
		return doctorAppUserService.addDoctorAppUser(doctor, operationTypeId, request);
	}


	@Override
	public List<DoctorModel> getDoctorByFuzzyName(String content) {
		DoctorAppUserExample ex = new DoctorAppUserExample();
		ex.createCriteria().andNameLike("%"+content+"%");
		List<DoctorAppUser> doctors = doctorAppUserMapper.selectByExample(ex);
		return transferModel(doctors);
	}


	@Override
	public List<DoctorModel> getDoctorByPhone(String content) {
		DoctorAppUserExample ex = new DoctorAppUserExample();
		ex.createCriteria().andPhoneEqualTo(content);
		List<DoctorAppUser> doctors = doctorAppUserMapper.selectByExample(ex);
		return transferModel(doctors);	
	}


	@Override
	public List<DoctorModel> getUnreviewDoctor(HttpServletRequest request) {
		DoctorAppUserExample ex = new DoctorAppUserExample();
		ex.createCriteria().andReviewStatusEqualTo(false);
		List<DoctorAppUser> doctors = doctorAppUserMapper.selectByExample(ex);
		return transferModel(doctors);
	}


	@Override
	public List<DoctorModel> getUnreviewDoctorByFuzzyName(String content) {
		DoctorAppUserExample ex = new DoctorAppUserExample();
		ex.createCriteria().andReviewStatusEqualTo(false).andNameLike("%"+content+"%");
		List<DoctorAppUser> doctors = doctorAppUserMapper.selectByExample(ex);
		return transferModel(doctors);
	}


	@Override
	public List<DoctorModel> getUnreviewDoctorByPhone(String content) {
		DoctorAppUserExample ex = new DoctorAppUserExample();
		ex.createCriteria().andReviewStatusEqualTo(false).andPhoneEqualTo(content);
		List<DoctorAppUser> doctors = doctorAppUserMapper.selectByExample(ex);
		return transferModel(doctors);
	}

	@Override
	public List<DoctorModel> getReviewDoctor(HttpServletRequest request) {
		DoctorAppUserExample ex = new DoctorAppUserExample();
		ex.createCriteria().andReviewStatusEqualTo(true);
		List<DoctorAppUser> doctors = doctorAppUserMapper.selectByExample(ex);
		return transferModel(doctors);
	}


	@Override
	public List<DoctorModel> getReviewDoctorByFuzzyName(String content) {
		DoctorAppUserExample ex = new DoctorAppUserExample();
		ex.createCriteria().andReviewStatusEqualTo(true).andNameLike("%"+content+"%");
		List<DoctorAppUser> doctors = doctorAppUserMapper.selectByExample(ex);
		return transferModel(doctors);
	}


	@Override
	public List<DoctorModel> getReviewDoctorByPhone(String content) {
		DoctorAppUserExample ex = new DoctorAppUserExample();
		ex.createCriteria().andReviewStatusEqualTo(true).andPhoneEqualTo(content);
		List<DoctorAppUser> doctors = doctorAppUserMapper.selectByExample(ex);
		return transferModel(doctors);
	}

	@Override
	public boolean addSubOperationType(SubOperationType subOperationType) {
		subOperationType.setDeleteFlag(false);
		return subOperationTypeMapper.insert(subOperationType) == 1;
	}

	@Override
	public List<SubOperationType> getSubOperationTypeByParentId(int parentId) {
		SubOperationTypeExample example = new SubOperationTypeExample();
		example.createCriteria().andParentIdEqualTo(parentId).andDeleteFlagEqualTo(false);
		return subOperationTypeMapper.selectByExample(example);
	}

	@Override
	public boolean deleteSubOperationTypeById(int id) {
		SubOperationType subOperationType = new SubOperationType();
		subOperationType.setId(id);
		subOperationType.setDeleteFlag(true);
		return subOperationTypeMapper.updateByPrimaryKeySelective(subOperationType) == 1;
	}

	@Override
	public List<SubOperationType> getAllSubOpertionType() {
		SubOperationTypeExample example = new SubOperationTypeExample();
		example.createCriteria().andDeleteFlagEqualTo(false);
		return subOperationTypeMapper.selectByExample(example);
	}

	@Override
	public OperationType getOperationTypeById(int parentId) {
		return operationTypeMapper.selectByPrimaryKey(parentId);
	}

	@Override
	public List<SubOperationType> getSubOperationTypeByParentIds(List<Integer> typeIds) {
		SubOperationTypeExample example = new SubOperationTypeExample();
		example.createCriteria().andParentIdIn(typeIds);
		return subOperationTypeMapper.selectByExample(example);
	}

	@Override
	public boolean resetDoctorPasswdById(int id) {
		DoctorAppUser d = new DoctorAppUser();
		d.setId(id);
		d.setPasswd(MD5Util.MD5("123456"));
		int i = doctorAppUserMapper.updateByPrimaryKeySelective(d);
		return i == 1;
	}

}
